home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / prev / prev.lha / gram.y < prev    next >
Text File  |  1991-03-12  |  22KB  |  1,163 lines

  1. /*
  2.  * parser for the input language to art
  3.  */
  4.  
  5. %{
  6. #include <stdio.h>
  7. #include <math.h>
  8. #include "art.h"
  9. #include "macro.h"
  10.  
  11. extern object    *objectinit(),
  12.         *compinit(),
  13.         *csginit(),
  14.         *getcsgobj(),
  15.         *getcsgexp();
  16.  
  17. extern symbol    *lookup();
  18.  
  19. extern light    *lightinit();
  20.  
  21. extern attr    *astackp;
  22. extern mats    *mstackp;
  23.  
  24. extern object    *oblist;
  25. extern light    *lights;
  26.  
  27. extern vector    eye, viewup, ref;
  28. extern int    lookatdone;
  29.  
  30. extern matrix    trans;
  31. extern float    fov;
  32. extern float    near;
  33.  
  34. extern char    *title;
  35. extern int    maxhitlevel, raysperpix, pixelgrid;
  36. extern long    filetype;
  37.  
  38. extern colour    backcol;
  39.  
  40. extern float    fogfactor, rfactor;
  41. extern colour    hazecolour;
  42.  
  43. extern float    sourceradius;
  44. extern float    falloff;
  45. extern float    ri;
  46.  
  47. extern float    twist;
  48. extern float    screenx, screeny;
  49. extern int    orthographic;
  50.  
  51. extern float        eval_fexpr();
  52. extern int        eval_iexpr();
  53. extern expression    *get_expr(), *get_varexpr();
  54.  
  55. #ifndef M_PI
  56. #define M_PI    3.14159265358979323846
  57. #endif
  58.  
  59. static int    objdefined = FALSE;
  60.  
  61. extern symbol    **ostackp;
  62.  
  63. %}
  64.  
  65. %union{
  66.     object        *y_obj;
  67.     light        *y_lht;
  68.     vector        *y_pnt;
  69.     details        *y_det;
  70.     char        *y_str;
  71.     eqn        *y_eqn;
  72.     term        *y_trm;
  73.     expression    *y_exp;
  74.     symbol        *y_sym;
  75.     csgnode        *y_csg;
  76.     float        y_flt;
  77.     int        y_int;
  78. };
  79.  
  80. %token        CSG
  81. %token        COMPOSITE
  82.  
  83. %token <y_sym>    OBJECT_TYPE
  84.  
  85. %token <y_flt>    FLOAT
  86. %token <y_int>    INTEGER FILETYPE OPTION
  87. %token <y_str>    NAME
  88.  
  89. %type  <y_exp>    expr 
  90. %type  <y_trm>    termlist term
  91. %type  <y_csg>    csgexpr
  92. %type  <y_det>    csgbody object definition vbody vitem
  93. %type  <y_det>    body bodyitem 
  94. %type  <y_det>    transform stlist compbody wbody witem mbody mitem
  95.  
  96. %token LBRACE RBRACE LP RP RADIUS RADII COLOUR CENTER VERTEX COMMA PCENT
  97. %token MATERIAL REFI MINUS AMBIENT LIGHT INTENSITY LOCATION NAME DOLS
  98. %token EQUATION TILE OFFFILE BASE TOP CONST COEFFS ART_SCALE ART_ROTATE
  99. %token ART_TRANSLATE PROJECTION ORTHOGRAPHIC PERSPECTIVE
  100. %token TITLE REFLECTANCE DOT ON OFF LOOKAT FIELDOFVIEW TRANSPARENCY
  101. %token RAYSPERPIXEL BACKGROUND SIZE MAXHITLEVEL OUTPUT FILETYPE ORDER
  102. %token ABSORPTION VREF1 VREF2 NUMRAYS OBJECT TEXTURE DIRECTION ANGLE UP
  103. %token TWENTYFIVEBIT RANGE MAP BLENDCOLOR SCALEFACTORS VORTFILE HAZECOLOUR
  104. %token FOGFACTOR RFACTOR FALLOFF QUOTE REPEAT SHADOWS COLOURFILE VNORMALFILE
  105. %token SCALEFACTOR SOURCE AMPLITUDE WAVELENGTH PHASE TURBULENCE SQUEEZE
  106. %token DAMPING SOURCERADIUS NORMAL COMPLEXVERTEX SCREENSIZE MAXTREEDEPTH
  107. %token BLEND COLOURMAP MAPVALUES PIXELGRID RI COLOURBLEND NORMALFILE
  108. %token BEAMDISTRIBUTION INSIDEANGLE
  109.  
  110. %left  PLUS MINUS
  111. %left  MULT DIV
  112. %left  POWER
  113. %left  UMINUS
  114.  
  115. %right  EQUALS
  116.  
  117. %%
  118.  
  119. input    : /* NULL */
  120.       {
  121.         objdefined = FALSE;
  122.       }
  123.     | input hitem
  124.     | input light
  125.     | input object
  126.       {
  127.         object    *obj, *head;
  128.  
  129.         if ((head = objectinit($2->u.obj.sym, $2->u.obj.det)) != (object *)NULL) {
  130.             for (obj = head; obj->nxt != (object *)NULL; obj = obj->nxt)    
  131.                 ;
  132.  
  133.             obj->nxt = oblist;
  134.             oblist = head;
  135.         }
  136.  
  137.         objdefined = TRUE;
  138.  
  139.         free($2);
  140.       }
  141.     | input statement
  142.     | input definition
  143.       {
  144.         objdefined = TRUE;
  145.  
  146.         free($2);
  147.       }
  148.     ;
  149.  
  150. hitem    : TITLE NAME
  151.     | FIELDOFVIEW expr
  152.       {
  153.         float   val;
  154.  
  155.         val = eval_fexpr($2);
  156.  
  157.         if (val == 0.0 || val == 360.0)
  158.             fatal("art: idiotic angle in field of view.\n");
  159.  
  160.         near = 1.0 / tan(M_PI / 360.0 * val);
  161.  
  162.         fov = val;
  163.       }
  164.     | SCREENSIZE expr COMMA expr
  165.       {
  166.         screenx = eval_fexpr($2) / 2.0;
  167.         screeny = eval_fexpr($4) / 2.0;
  168.       }
  169.     | MAXTREEDEPTH expr
  170.     | RAYSPERPIXEL expr
  171.     | HAZECOLOUR expr COMMA expr COMMA expr
  172.     | FOGFACTOR expr
  173.     | RFACTOR expr
  174.     | SOURCERADIUS expr
  175.     | PROJECTION PERSPECTIVE
  176.       {
  177.         orthographic = FALSE;
  178.       }
  179.     | PROJECTION ORTHOGRAPHIC
  180.       {
  181.         orthographic = TRUE;
  182.       }
  183.     | PIXELGRID ON
  184.     | TWENTYFIVEBIT ON
  185.     | TWENTYFIVEBIT OFF
  186.     | UP LP expr COMMA expr COMMA expr RP
  187.       {
  188.         viewup.x = eval_fexpr($3);
  189.         viewup.y = eval_fexpr($5);
  190.         viewup.z = eval_fexpr($7);
  191.  
  192.       }
  193.     | LOOKAT LP expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr RP
  194.       {
  195.         vector    t, u, s;
  196.         matrix    m, tmp;
  197.         double    val, vy, vz, sinval, cosval;
  198.  
  199.         twist = -eval_fexpr($15);
  200.  
  201.         eye.x = eval_fexpr($3);
  202.         eye.y = eval_fexpr($5);
  203.         eye.z = eval_fexpr($7);
  204.  
  205.         ref.x = eval_fexpr($9);
  206.         ref.y = eval_fexpr($11);
  207.         ref.z = eval_fexpr($13);
  208.  
  209.         fprintf(stderr, "eye: %f %f %f\n", eye.x, eye.y, eye.z);
  210.         fprintf(stderr, "ref: %f %f %f\n", ref.x, ref.y, ref.z);
  211.         fprintf(stderr, "twist: %f\n", twist);
  212.         fprintf(stderr, "fov: %f\n", fov);
  213.  
  214.       }
  215.     | BACKGROUND expr COMMA expr COMMA expr
  216.     | MAXHITLEVEL expr
  217.     | OUTPUT FILETYPE
  218.     | FALLOFF expr
  219.     | RI expr
  220.     | SHADOWS OFF
  221.     ;
  222.  
  223. light    : LIGHT LBRACE lbody RBRACE
  224.     ;
  225.  
  226. lbody    : /* NULL */
  227.     | lbody litem
  228.     ;
  229.  
  230. litem    : LOCATION LP expr COMMA expr COMMA expr RP
  231.     | RADIUS expr
  232.     | NUMRAYS expr
  233.     | INSIDEANGLE expr
  234.     | BEAMDISTRIBUTION expr
  235.     | ANGLE expr
  236.     | DIRECTION LP expr COMMA expr COMMA expr RP
  237.     | COLOUR expr COMMA expr COMMA expr
  238.     | SHADOWS OFF
  239.     ;
  240.  
  241. object    : OBJECT_TYPE LBRACE body RBRACE
  242.       {
  243.         $$ = (details *)smalloc(sizeof(details));
  244.         $$->type = OBJECT;
  245.         $$->u.obj.sym = $1;
  246.         $$->u.obj.det = $3;
  247.         $$->nxt = (details *)NULL;
  248.       }
  249.     | OBJECT_TYPE
  250.       {
  251.         $$ = (details *)smalloc(sizeof(details));
  252.         $$->type = OBJECT;
  253.         $$->u.obj.sym = $1;
  254.         $$->u.obj.det = (details *)NULL;
  255.         $$->nxt = (details *)NULL;
  256.       }
  257.     | COMPOSITE LBRACE compbody RBRACE
  258.       {
  259.         $$ = (details *)smalloc(sizeof(details));
  260.         $$->type = COMP_OBJ;
  261.         $$->u.obj.sym = (symbol *)NULL;
  262.         $$->u.obj.det = $3;
  263.         $$->nxt = (details *)NULL;
  264.       }
  265.     | CSG LBRACE 
  266.       {
  267.         ostackp++;
  268.         *ostackp = (symbol *)NULL;
  269.       }
  270.       csgbody csgexpr RBRACE
  271.       {
  272.         details    *d;
  273.         symbol    *s;
  274.  
  275.         ostackp--;
  276.  
  277.         d = (details *)smalloc(sizeof(details));
  278.         d->type = $4->type;
  279.         d->u.csgobj.tree = $5;
  280.         d->u.csgobj.det = $4;
  281.         d->nxt = (details *)NULL;
  282.  
  283.         s = (symbol *)smalloc(sizeof(symbol));
  284.         s->type = CSG_OBJ;
  285.         s->u.det = d;
  286.  
  287.         $$ = (details *)smalloc(sizeof(details));
  288.         $$->type = OBJECT;
  289.         $$->u.obj.sym = s;
  290.         $$->u.obj.det = (details *)NULL;
  291.         $$->nxt = (details *)NULL;
  292.       }
  293.     ;
  294.  
  295. compbody: /* NULL */
  296.       {
  297.         $$ = (details *)NULL;
  298.       }
  299.     | compbody transform
  300.       {
  301.         $$ = $2;
  302.         $2->nxt = $1;
  303.       }
  304.     | compbody bodyitem
  305.       {
  306.         $$ = $2;
  307.         $2->nxt = $1;
  308.       }
  309.     | compbody object
  310.       {
  311.         $$ = $2;
  312.         $2->nxt = $1;
  313.       }
  314.     ;
  315.  
  316. statement: NAME EQUALS expr
  317.       {
  318.         defvar($1, $3);
  319.       }
  320.     | transform
  321.       {
  322.         switch ($1->type) {
  323.         case ART_TRANSLATE:
  324.             translate($1->u.v.x, $1->u.v.y, $1->u.v.z);
  325.             break;
  326.         case ART_SCALE:
  327.             scale($1->u.v.x, $1->u.v.y, $1->u.v.z);
  328.             break;
  329.         case ART_ROTATE:
  330.             rotate($1->u.rot.ang, $1->u.rot.axis);
  331.             break;
  332.         default:
  333.             fatal("art: bad transform type in switch.\n");
  334.         }
  335.  
  336.         free($1);
  337.       }
  338.     | bodyitem
  339.       {
  340.         surface    *s;
  341.  
  342.             /*
  343.              * don't want to change someone else's
  344.              * material properties
  345.              */
  346.         if (objdefined) {
  347.             s = (surface *)smalloc(sizeof(surface));
  348.             *s = *astackp->s;
  349.             astackp->s = s;
  350.         } else
  351.             s = astackp->s;
  352.  
  353.         switch ($1->type) {
  354.         case COLOUR:
  355.             s->c.r = $1->u.c.r;
  356.             s->c.g = $1->u.c.g;
  357.             s->c.b = $1->u.c.b;
  358.             break;
  359.         case AMBIENT:
  360.             s->a.r = $1->u.c.r;
  361.             s->a.g = $1->u.c.g;
  362.             s->a.b = $1->u.c.b;
  363.             break;
  364.         case TEXTURE:
  365.             break;
  366.         case MATERIAL:
  367.             s->ri = $1->u.mat.ri;
  368.             s->kd = $1->u.mat.kd;
  369.             s->ks = $1->u.mat.ks;
  370.             s->ksexp = $1->u.mat.ksexp;
  371.             break;
  372.         case REFLECTANCE:
  373.             s->refl = $1->u.f;
  374.             break;
  375.         case TRANSPARENCY:
  376.             s->trans = $1->u.f;
  377.             break;
  378.         case ABSORPTION:
  379.             s->falloff = $1->u.f;
  380.             break;
  381.         case ON:
  382.             astackp->options |= $1->u.i;
  383.             break;
  384.         case OFF:
  385.             astackp->options &= ~$1->u.i;
  386.             break;
  387.         default:
  388.             fatal("art: bad statement type in switch.\n");
  389.         }
  390.  
  391.         free($1);
  392.       }
  393.     | REPEAT expr LBRACE stlist RBRACE
  394.       {
  395.         dorepeat($2, $4);
  396.       }
  397.     ;
  398.  
  399. stlist    : /* NULL */
  400.       {
  401.         $$ = (details *)NULL;
  402.       }
  403.     | stlist transform
  404.       {
  405.         $2->nxt = $1;
  406.         $$ = $2;
  407.       }
  408.     | stlist OBJECT_TYPE
  409.       {
  410.         $$ = (details *)smalloc(sizeof(details));
  411.  
  412.         $$->type = OBJECT;
  413.         $$->u.sym = $2;
  414.         $$->nxt = $1;
  415.       }
  416.     | stlist REPEAT expr LBRACE stlist RBRACE
  417.       {
  418.         $$ = (details *)smalloc(sizeof(details));
  419.  
  420.         $$->type = REPEAT;
  421.         $$->u.rpt.expr = $3;
  422.         $$->u.rpt.stmt = $5;
  423.         $$->nxt = $1;
  424.       }
  425.     ;
  426.         
  427.  
  428. body    : /* NULL */
  429.       {
  430.         $$ = (details *)NULL;
  431.       }
  432.     | body transform
  433.       {
  434.         $2->nxt = $1;
  435.         $$ = $2;
  436.       }
  437.     | body bodyitem
  438.       {
  439.         $2->nxt = $1;
  440.         $$ = $2;
  441.       }
  442.     ;
  443.  
  444. bodyitem: CENTER LP expr COMMA expr COMMA expr RP
  445.       {
  446.         $$ = (details *)smalloc(sizeof(details));
  447.         $$->type = CENTER;
  448.         $$->u.v.x = eval_fexpr($3);
  449.         $$->u.v.y = eval_fexpr($5);
  450.         $$->u.v.z = eval_fexpr($7);
  451.         $$->nxt = (details *)NULL;
  452.       }
  453.     | ORDER expr
  454.       {
  455.         $$ = (details *)smalloc(sizeof(details));
  456.         $$->type = ORDER;
  457.         $$->u.i = eval_iexpr($2);
  458.         $$->nxt = (details *)NULL;
  459.       }
  460.     | RADIUS expr
  461.       {
  462.         $$ = (details *)smalloc(sizeof(details));
  463.         $$->type = RADIUS;
  464.         $$->u.f = eval_fexpr($2);
  465.         $$->nxt = (details *)NULL;
  466.       }
  467.     | RADII expr COMMA expr
  468.       {
  469.         $$ = (details *)smalloc(sizeof(details));
  470.         $$->type = RADII;
  471.         $$->u.v.x = eval_fexpr($2);
  472.         $$->u.v.y = eval_fexpr($4);
  473.         $$->nxt = (details *)NULL;
  474.       }
  475.     | RADII expr COMMA expr COMMA expr
  476.       {
  477.         $$ = (details *)smalloc(sizeof(details));
  478.         $$->type = RADII;
  479.         $$->u.v.x = eval_fexpr($2);
  480.         $$->u.v.y = eval_fexpr($4);
  481.         $$->u.v.z = eval_fexpr($6);
  482.         $$->nxt = (details *)NULL;
  483.       }
  484.     | VERTEX vbody
  485.       {
  486.         if ($2->nxt == (details *)NULL) {
  487.             $2->type = VERTEX;
  488.             $$ = $2;
  489.         } else {
  490.             $$ = (details *)smalloc(sizeof(details));
  491.             $$->type = COMPLEXVERTEX;
  492.             $$->u.det = $2;
  493.             $$->nxt = (details *)NULL;
  494.         }
  495.       }
  496.     | EQUATION DOLS termlist EQUALS expr DOLS
  497.       {
  498.         $$ = (details *)smalloc(sizeof(details));
  499.         $$->type = EQUATION;
  500.         $$->u.t = (term *)smalloc(sizeof(term));
  501.         $$->u.t->coef = -eval_fexpr($5);
  502.         $$->u.t->xp = 0;
  503.         $$->u.t->yp = 0;
  504.         $$->u.t->zp = 0;
  505.         $$->u.t->nxt = $3;
  506.         $$->nxt = (details *)NULL;
  507.       }
  508.     | COEFFS expr COMMA expr COMMA expr
  509.       {
  510.         $$ = (details *)smalloc(sizeof(details));
  511.         $$->type = COEFFS;
  512.         $$->u.v.x = eval_fexpr($2);
  513.         $$->u.v.y = eval_fexpr($4);
  514.         $$->u.v.z = eval_fexpr($6);
  515.         $$->nxt = (details *)NULL;
  516.       }
  517.     | CONST expr
  518.       {
  519.         $$ = (details *)smalloc(sizeof(details));
  520.         $$->type = CONST;
  521.         $$->u.f = eval_fexpr($2);
  522.         $$->nxt = (details *)NULL;
  523.       }
  524.     | TOP expr
  525.       {
  526.         $$ = (details *)smalloc(sizeof(details));
  527.         $$->type = TOP;
  528.         $$->u.f = eval_fexpr($2);
  529.         $$->nxt = (details *)NULL;
  530.       }
  531.     | BASE expr
  532.       {
  533.         $$ = (details *)smalloc(sizeof(details));
  534.         $$->type = BASE;
  535.         $$->u.f = eval_fexpr($2);
  536.         $$->nxt = (details *)NULL;
  537.       }
  538.     | OFFFILE NAME
  539.       {
  540.         $$ = (details *)smalloc(sizeof(details));
  541.         $$->type = OFFFILE;
  542.         $$->u.s = $2;
  543.         $$->nxt = (details *)NULL;
  544.       }
  545.     | COLOURFILE NAME
  546.       {
  547.         $$ = (details *)smalloc(sizeof(details));
  548.         $$->type = COLOURFILE;
  549.         $$->u.s = $2;
  550.         $$->nxt = (details *)NULL;
  551.       }
  552.     | VNORMALFILE NAME
  553.       {
  554.         $$ = (details *)smalloc(sizeof(details));
  555.         $$->type = VNORMALFILE;
  556.         $$->u.s = $2;
  557.         $$->nxt = (details *)NULL;
  558.       }
  559.     | NORMALFILE NAME
  560.       {
  561.         $$ = (details *)smalloc(sizeof(details));
  562.         $$->type = NORMALFILE;
  563.         $$->u.s = $2;
  564.         $$->nxt = (details *)NULL;
  565.       }
  566.     | COLOUR expr COMMA expr COMMA expr
  567.       {
  568.         $$ = (details *)smalloc(sizeof(details));
  569.         $$->type = COLOUR;
  570.         $$->u.c.r = eval_fexpr($2);
  571.         $$->u.c.g = eval_fexpr($4);
  572.         $$->u.c.b = eval_fexpr($6);
  573.         $$->nxt = (details *)NULL;
  574.       }
  575.     | MATERIAL expr COMMA expr COMMA expr COMMA expr
  576.       {
  577.         $$ = (details *)smalloc(sizeof(details));
  578.         $$->type = MATERIAL;
  579.         $$->u.mat.ri = eval_fexpr($2);
  580.         $$->u.mat.kd = eval_fexpr($4);
  581.         $$->u.mat.ks = eval_fexpr($6);
  582.         $$->u.mat.ksexp = eval_iexpr($8);
  583.         $$->nxt = (details *)NULL;
  584.       }
  585.     | AMBIENT expr COMMA expr COMMA expr
  586.       {
  587.         $$ = (details *)smalloc(sizeof(details));
  588.         $$->type = AMBIENT;
  589.         $$->u.v.x = eval_fexpr($2);
  590.         $$->u.v.y = eval_fexpr($4);
  591.         $$->u.v.z = eval_fexpr($6);
  592.         $$->nxt = (details *)NULL;
  593.       }
  594.     | REFLECTANCE expr
  595.       {
  596.         $$ = (details *)smalloc(sizeof(details));
  597.         $$->type = REFLECTANCE;
  598.         $$->u.f = eval_fexpr($2);
  599.         $$->nxt = (details *)NULL;
  600.       }
  601.     | TRANSPARENCY expr
  602.       {
  603.         $$ = (details *)smalloc(sizeof(details));
  604.         $$->type = TRANSPARENCY;
  605.         $$->u.f = eval_fexpr($2);
  606.         $$->nxt = (details *)NULL;
  607.       }
  608.     | ABSORPTION expr
  609.       {
  610.         $$ = (details *)smalloc(sizeof(details));
  611.         $$->type = ABSORPTION;
  612.         $$->u.f = eval_fexpr($2);
  613.         $$->nxt = (details *)NULL;
  614.       }
  615.     | OPTION ON
  616.       {
  617.         $$ = (details *)smalloc(sizeof(details));
  618.         $$->type = ON;
  619.         $$->u.i = $1;
  620.         $$->nxt = (details *)NULL;
  621.       }
  622.     | OPTION OFF
  623.       {
  624.         $$ = (details *)smalloc(sizeof(details));
  625.         $$->type = OFF;
  626.         $$->u.i = $1;
  627.         $$->nxt = (details *)NULL;
  628.       }
  629.     | TEXTURE NAME LBRACE texture_ops RBRACE
  630.       {
  631.         $$ = (details *)smalloc(sizeof(details));
  632.         $$->type = TEXTURE;
  633.         $$->nxt = (details *)NULL;
  634.       }
  635.     | TEXTURE NAME textitem 
  636.       {
  637.         $$ = (details *)smalloc(sizeof(details));
  638.         $$->type = TEXTURE;
  639.         $$->nxt = (details *)NULL;
  640.       }
  641.     | TEXTURE TILE textitem 
  642.       {
  643.         $$ = (details *)smalloc(sizeof(details));
  644.         $$->type = TEXTURE;
  645.         $$->nxt = (details *)NULL;
  646.       }
  647.     | TEXTURE TILE LBRACE texture_ops RBRACE
  648.       {
  649.         $$ = (details *)smalloc(sizeof(details));
  650.         $$->type = TEXTURE;
  651.         $$->nxt = (details *)NULL;
  652.       }
  653.     | TILE NAME SIZE expr COMMA expr
  654.       {
  655.         details    *d1, *d2;
  656.  
  657.         d1 = (details *)smalloc(sizeof(details));
  658.         d1->type = VORTFILE;
  659.         d1->u.s = $2;
  660.  
  661.         d2 = (details *)smalloc(sizeof(details));
  662.         d2->type = SIZE;
  663.         d2->u.v.x = eval_fexpr($4);
  664.         d2->u.v.y = eval_fexpr($6);
  665.  
  666.         d1->nxt = d2;
  667.         d2->nxt = (details *)NULL;
  668.  
  669.         $$ = (details *)smalloc(sizeof(details));
  670.         $$->type = TEXTURE;
  671.         $$->nxt = (details *)NULL;
  672.       }
  673.     ;
  674.  
  675. vbody    : vitem
  676.       {
  677.         $$ = $1;
  678.       }
  679.     | vbody COMMA vitem
  680.       {
  681.         $3->nxt = $1;
  682.         $$ = $3;
  683.       }
  684.     ;
  685.  
  686. vitem    : LP expr COMMA expr COMMA expr RP
  687.       {
  688.         $$ = (details *)smalloc(sizeof(details));
  689.         $$->type = VERTEX;
  690.         $$->u.v.x = eval_fexpr($2);
  691.         $$->u.v.y = eval_fexpr($4);
  692.         $$->u.v.z = eval_fexpr($6);
  693.         $$->nxt = (details *)NULL;
  694.       }
  695.     | expr COMMA expr COMMA expr
  696.       {
  697.         $$ = (details *)smalloc(sizeof(details));
  698.         $$->type = COLOUR;
  699.         $$->u.v.x = eval_fexpr($1);
  700.         $$->u.v.y = eval_fexpr($3);
  701.         $$->u.v.z = eval_fexpr($5);
  702.         $$->nxt = (details *)NULL;
  703.       }
  704.  
  705. transform: ART_ROTATE LP expr COMMA expr RP
  706.       {
  707.         $$ = (details *)smalloc(sizeof(details));
  708.         $$->type = ART_ROTATE;
  709.         $$->u.rot.ang = eval_fexpr($3);
  710.         $$->u.rot.axis = eval_iexpr($5);
  711.         $$->nxt = (details *)NULL;
  712.       }
  713.     | ART_TRANSLATE LP expr COMMA expr COMMA expr RP
  714.       {
  715.         $$ = (details *)smalloc(sizeof(details));
  716.         $$->type = ART_TRANSLATE;
  717.         $$->u.v.x = eval_fexpr($3);
  718.         $$->u.v.y = eval_fexpr($5);
  719.         $$->u.v.z = eval_fexpr($7);
  720.         $$->nxt = (details *)NULL;
  721.       }
  722.     | ART_SCALE LP expr COMMA expr COMMA expr RP
  723.       {
  724.         $$ = (details *)smalloc(sizeof(details));
  725.         $$->type = ART_SCALE;
  726.         $$->u.v.x = eval_fexpr($3);
  727.         $$->u.v.y = eval_fexpr($5);
  728.         $$->u.v.z = eval_fexpr($7);
  729.         $$->nxt = (details *)NULL;
  730.       }
  731.     ;
  732.  
  733. texture_ops:    /* NULL */
  734.     | texture_ops textitem
  735.     | texture_ops transform
  736.     ;
  737.  
  738. textitem: MAP NAME
  739.     | COLOURMAP LBRACE mbody RBRACE
  740.     | BLEND expr
  741.     | RANGE expr
  742.     | BLENDCOLOR expr COMMA expr COMMA expr
  743.     | SIZE expr COMMA expr
  744.     | SCALEFACTORS expr COMMA expr COMMA expr
  745.     | SCALEFACTOR expr
  746.     | VORTFILE NAME
  747.     | TURBULENCE expr
  748.     | SQUEEZE expr
  749.     | SOURCE LBRACE wbody RBRACE
  750.     ;
  751.  
  752. mbody    : mitem
  753.     {
  754.         $$ = (details *)NULL;
  755.     }
  756.     | mbody COMMA mitem
  757.     {
  758.         $3->nxt = $1;
  759.         $$ = $3;
  760.     }
  761.     ;
  762.  
  763. mitem   : expr COMMA expr COMMA expr
  764.           {
  765.                 $$ = (details *)smalloc(sizeof(details));
  766.                 $$->type = MAPVALUES;
  767.                 $$->u.v.x = eval_fexpr($1);
  768.                 $$->u.v.y = eval_fexpr($3);
  769.                 $$->u.v.z = eval_fexpr($5);
  770.                 $$->nxt = (details *)NULL;
  771.       }
  772.     ;
  773. wbody   : /* NULL */
  774.           {
  775.                 $$ = (details *)NULL;
  776.           }
  777.         | wbody witem
  778.           {
  779.                 $2->nxt = $1;
  780.                 $$ = $2;
  781.           }
  782.         ;
  783.  
  784. witem   : CENTER LP expr COMMA expr COMMA expr RP
  785.           {
  786.                 $$ = (details *)smalloc(sizeof(details));
  787.                 $$->type = CENTER;
  788.                 $$->u.v.x = eval_fexpr($3);
  789.                 $$->u.v.y = eval_fexpr($5);
  790.                 $$->u.v.z = eval_fexpr($7);
  791.                 $$->nxt = (details *)NULL;
  792.       }
  793.     | WAVELENGTH expr
  794.       {
  795.                 $$ = (details *)smalloc(sizeof(details));
  796.                 $$->type = WAVELENGTH;
  797.                 $$->u.f = eval_fexpr($2);
  798.                 $$->nxt = (details *)NULL;
  799.       }
  800.     | AMPLITUDE expr
  801.       {
  802.                 $$ = (details *)smalloc(sizeof(details));
  803.                 $$->type = AMPLITUDE;
  804.                 $$->u.f = eval_fexpr($2);
  805.                 $$->nxt = (details *)NULL;
  806.       }
  807.     | PHASE expr
  808.       {
  809.                 $$ = (details *)smalloc(sizeof(details));
  810.                 $$->type = PHASE;
  811.                 $$->u.f = eval_fexpr($2);
  812.                 $$->nxt = (details *)NULL;
  813.       }
  814.     | DAMPING expr
  815.       {
  816.                 $$ = (details *)smalloc(sizeof(details));
  817.                 $$->type = DAMPING;
  818.                 $$->u.f = eval_fexpr($2);
  819.                 $$->nxt = (details *)NULL;
  820.       }
  821.     ;
  822.  
  823.  
  824. csgbody    : /* NULL */
  825.       {
  826.         $$ = (details *)NULL;
  827.       }
  828.     | csgbody bodyitem
  829.       {
  830.         $2->nxt = $1;
  831.         $$ = $2;
  832.       }
  833.     | csgbody transform
  834.       {
  835.         $2->nxt = $1;
  836.         $$ = $2;
  837.       }
  838.     | csgbody definition
  839.       {
  840.         $2->nxt = $1;
  841.         $$ = $2;
  842.       }
  843.     ;
  844.  
  845. definition: OBJECT_TYPE NAME LBRACE body RBRACE
  846.       {
  847.         defobj($2, $1->type, $4);
  848.  
  849.         $$ = (details *)smalloc(sizeof(details));
  850.  
  851.         $$->type = OBJECT;
  852.         $$->u.sym = lookup($2);
  853.         $$->nxt = (details *)NULL;
  854.       }
  855.     | CSG NAME LBRACE
  856.       {
  857.         ostackp++;
  858.         *ostackp = (symbol *)NULL;
  859.       }
  860.       csgbody csgexpr RBRACE
  861.       {
  862.         details    *d;
  863.  
  864.         ostackp--;
  865.  
  866.         d = (details *)smalloc(sizeof(details));
  867.  
  868.         d->type = $6->type;
  869.         d->u.csgobj.tree = $6;
  870.         d->u.csgobj.det = $5;
  871.         d->nxt = (details *)NULL;
  872.  
  873.         defobj($2, CSG_OBJ, d);
  874.  
  875.         $$ = (details *)smalloc(sizeof(details));
  876.  
  877.         $$->type = OBJECT;
  878.         $$->u.sym = lookup($2);
  879.         $$->nxt = (details *)NULL;
  880.       }
  881.     | COMPOSITE NAME LBRACE compbody RBRACE
  882.       {
  883.         defobj($2, COMP_OBJ, $4);
  884.  
  885.         $$ = (details *)smalloc(sizeof(details));
  886.  
  887.         $$->type = OBJECT;
  888.         $$->u.sym = lookup($2);
  889.         $$->nxt = (details *)NULL;
  890.       }
  891.     ;
  892.  
  893.  
  894. csgexpr    : OBJECT_TYPE
  895.       {
  896.         $$ = (csgnode *)smalloc(sizeof(csgnode));
  897.         $$->type = OBJECT;
  898.         $$->u.sym = $1;
  899.       }
  900.     | csgexpr PLUS csgexpr
  901.       {
  902.         $$ = (csgnode *)smalloc(sizeof(csgnode));
  903.         $$->type = CSG_ADD;
  904.         $$->u.branch.left = $1;
  905.         $$->u.branch.right = $3;
  906.       }
  907.     | csgexpr MULT csgexpr
  908.       {
  909.         $$ = (csgnode *)smalloc(sizeof(csgnode));
  910.         $$->type = CSG_INT;
  911.         $$->u.branch.left = $1;
  912.         $$->u.branch.right = $3;
  913.       }
  914.     | csgexpr MINUS csgexpr
  915.       {
  916.         $$ = (csgnode *)smalloc(sizeof(csgnode));
  917.         $$->type = CSG_SUB;
  918.         $$->u.branch.left = $1;
  919.         $$->u.branch.right = $3;
  920.       }
  921.     | LP csgexpr RP
  922.       {
  923.         $$ = $2;
  924.       }
  925.     | NAME
  926.       {
  927.         char    buf[BUFSIZ];
  928.  
  929.         sprintf(buf, "art: object %s not defined.\n", $1);
  930.         fatal(buf);
  931.       }
  932.     ;
  933.  
  934. termlist: term
  935.       {
  936.         $$ = $1;
  937.       }
  938.     | termlist termlist %prec MULT
  939.       {
  940.         term    *t, *p, *np, *prod;
  941.  
  942.         prod = (term *)NULL;
  943.         for (p = $1; p != (term *)NULL; p = p->nxt) {
  944.             for (np = $2; np != (term *)NULL; np = np->nxt) {
  945.                 t = (term *)smalloc(sizeof(term));
  946.                 *t = *np;
  947.                 t->coef *= p->coef;
  948.                 t->xp += p->xp;
  949.                 t->yp += p->yp;
  950.                 t->zp += p->zp;
  951.                 t->nxt = prod;
  952.                 prod = t;
  953.             }
  954.         }
  955.  
  956.         for (t = $1; t != (term *)NULL; t = np) {
  957.             np = t->nxt;
  958.             free(t);
  959.         }
  960.  
  961.         for (t = $2; t != (term *)NULL; t = np) {
  962.             np = t->nxt;
  963.             free(t);
  964.         }
  965.  
  966.         $$ = prod;
  967.       }
  968.     | LP termlist RP 
  969.       {
  970.         $$ = $2;
  971.       }
  972.     | LP termlist RP POWER LBRACE INTEGER RBRACE
  973.       {
  974.         term    *t, *p, *np, *prod, *nprod;
  975.         int    i;
  976.  
  977.         prod = $2;
  978.  
  979.         for (i = 1; i != $6; i++) {        
  980.             nprod = (term *)NULL;
  981.             for (p = $2; p != (term *)NULL; p = p->nxt) {
  982.                 for (np = prod; np != (term *)NULL; np = np->nxt) {
  983.                     t = (term *)smalloc(sizeof(term));
  984.                     *t = *np;
  985.                     t->coef *= p->coef;
  986.                     t->xp += p->xp;
  987.                     t->yp += p->yp;
  988.                     t->zp += p->zp;
  989.                     t->nxt = nprod;
  990.                     nprod = t;
  991.                 }
  992.             }
  993.             if (prod != $2)
  994.                 for (t = prod; t != (term *)NULL; t = np) {
  995.                     np = t->nxt;
  996.                     free(t);
  997.                 }
  998.             prod = nprod;
  999.         }
  1000.  
  1001.         for (t = $2; t != (term *)NULL; t = np) {
  1002.             np = t->nxt;
  1003.             free(t);
  1004.         }
  1005.  
  1006.         $$ = prod;
  1007.       }
  1008.     | termlist PLUS termlist
  1009.       {
  1010.         term    *p;
  1011.  
  1012.         for (p = $3; p->nxt != (term *)NULL; p = p->nxt)
  1013.             ;
  1014.         $$ = $3;
  1015.         p->nxt = $1;
  1016.       }
  1017.     | termlist MINUS termlist
  1018.       {
  1019.         term    *p, *lp;
  1020.  
  1021.         for (p = $3; p != (term *)NULL; p = p->nxt) {
  1022.             p->coef *= -1.0;
  1023.             lp = p;
  1024.         }
  1025.  
  1026.         $$ = $3;
  1027.         lp->nxt = $1;
  1028.       }
  1029.     ;
  1030.  
  1031. term    : NAME
  1032.       {
  1033.         char    *p;
  1034.  
  1035.         $$ = (term *)smalloc(sizeof(term));
  1036.         $$->coef = 1;
  1037.         $$->xp = 0;
  1038.         $$->yp = 0;
  1039.         $$->zp = 0;
  1040.         $$->nxt = (term *)NULL;
  1041.  
  1042.         for (p = $1; *p != 0; p++)
  1043.             switch (*p) {
  1044.             case 'x':
  1045.                 $$->xp += 1;
  1046.                 break;
  1047.             case 'y':
  1048.                 $$->yp += 1;
  1049.                 break;
  1050.             case 'z':
  1051.                 $$->zp += 1;
  1052.                 break;
  1053.             default:
  1054.                 fatal("art: illegal name in equation.\n");
  1055.             }
  1056.       }
  1057.     | FLOAT
  1058.       {
  1059.         $$ = (term *)smalloc(sizeof(term));
  1060.         $$->coef = $1;
  1061.         $$->xp = 0;
  1062.         $$->yp = 0;
  1063.         $$->zp = 0;
  1064.         $$->nxt = (term *)NULL;
  1065.       }
  1066.     | INTEGER
  1067.       {
  1068.         $$ = (term *)smalloc(sizeof(term));
  1069.         $$->coef = $1;
  1070.         $$->xp = 0;
  1071.         $$->yp = 0;
  1072.         $$->zp = 0;
  1073.         $$->nxt = (term *)NULL;
  1074.       }
  1075.     | NAME POWER LBRACE INTEGER RBRACE
  1076.       {
  1077.         char    *p;
  1078.  
  1079.         $$ = (term *)smalloc(sizeof(term));
  1080.         $$->coef = 1;
  1081.         $$->xp = 0;
  1082.         $$->yp = 0;
  1083.         $$->zp = 0;
  1084.         $$->nxt = (term *)NULL;
  1085.  
  1086.         for (p = $1; *p != 0; p++)
  1087.             switch (*p) {
  1088.             case 'x':
  1089.                 $$->xp += 1;
  1090.                 break;
  1091.             case 'y':
  1092.                 $$->yp += 1;
  1093.                 break;
  1094.             case 'z':
  1095.                 $$->zp += 1;
  1096.                 break;
  1097.             default:
  1098.                 fatal("art: illegal name in equation.\n");
  1099.             }
  1100.  
  1101.         p--;
  1102.  
  1103.         switch (*p) {
  1104.         case 'x':
  1105.             $$->xp += $4 - 1;
  1106.             break;
  1107.         case 'y':
  1108.             $$->yp += $4 - 1;
  1109.             break;
  1110.         case 'z':
  1111.             $$->zp += $4 - 1;
  1112.             break;
  1113.         default:
  1114.             fatal("art: illegal name in equation.\n");
  1115.         }
  1116.       }
  1117.     ;
  1118.  
  1119. expr    : FLOAT
  1120.       {
  1121.         $$ = (expression *)smalloc(sizeof(expression));
  1122.         $$->type = EXP_FLOAT;
  1123.         $$->u.f = $1;
  1124.       }
  1125.     | INTEGER
  1126.       {
  1127.         $$ = (expression *)smalloc(sizeof(expression));
  1128.         $$->type = EXP_INT;
  1129.         $$->u.i = $1;
  1130.       }
  1131.     | QUOTE NAME QUOTE
  1132.       {
  1133.         $$ = (expression *)smalloc(sizeof(expression));
  1134.         $$->type = EXP_INT;
  1135.         $$->u.i = *$2;
  1136.         free($2);
  1137.       }
  1138.     | NAME
  1139.       {
  1140.         $$ = get_varexpr($1);
  1141.       }
  1142.     | expr PLUS expr
  1143.       {
  1144.         $$ = get_expr(EXP_ADD, $1, $3);
  1145.       }
  1146.     | expr MINUS expr
  1147.       {
  1148.         $$ = get_expr(EXP_SUB, $1, $3);
  1149.       }
  1150.     | expr MULT expr
  1151.       {
  1152.         $$ = get_expr(EXP_MUL, $1, $3);
  1153.       }
  1154.     | expr DIV expr
  1155.       {
  1156.         $$ = get_expr(EXP_DIV, $1, $3);
  1157.       }
  1158.     | MINUS expr %prec UMINUS
  1159.       {
  1160.         $$ = get_expr(EXP_UMINUS, $2, (expression *)NULL);
  1161.       }
  1162.     ;
  1163.